package com.boarsoft.boar.deploy.app;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Lazy;

import com.boarsoft.agent.AgentService;
import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.BaseConfig;
import com.boarsoft.boar.deploy.bean.DeployAppInstParam;
import com.boarsoft.boar.deploy.entity.AppDeployInfo;
import com.boarsoft.common.Util;
import com.boarsoft.flow.core.bean.ProcessHandler;
import com.boarsoft.rpc.core.RpcContext;

/**
 * 启动应用
 * 
 * @author Mac_J
 *
 */
public class StartInstPH implements ProcessHandler {
	private static final Logger log = LoggerFactory.getLogger(StartInstPH.class);

	@Autowired
	@Lazy(value = true)
	@Qualifier("agentX")
	protected AgentService agentX;

	/** 用于启动的脚本名 */
	protected String shell;

	@Override
	public Object process(String entry, Object data, Throwable throwable) throws Throwable {
		DeployAppInstParam p = (DeployAppInstParam) data;
		AppDeployInfo app = p.getApp();
		String axa = new StringBuilder().append(p.getIp()).append(":")//
				.append(BaseConfig.AGENTX_PORT).toString();
		String cmd = shell;
		if (Util.strIsEmpty(cmd)) {
			cmd = app.getStartCode();
		}
		String dp = p.getTargetPath();
		log.info("Ask {} startup app instance {} with: {}", axa, p.getAddr(), cmd);
		// 取inst的path而不是app的deployPath
		RpcContext.specify2(axa);
		try {
			// 执行应用实例目录下的启动脚本
			ReplyInfo<Object> ro = agentX.executeShell(//
					dp, cmd, new String[] { dp, p.getIp(), String.valueOf(p.getPort()) });
			if (ro.isSuccess()) {
				log.info("App instance {} is started successfully", p.getAddr());
				return data;
			}
			throw new Exception(new StringBuilder("AgentX ").append(axa)//
					.append(" start app instance ").append(p.getAddr())//
					.append(" failed, reason: ")//
					.append(ro.getData()).toString());
		} finally {
			RpcContext.specify2(null);
		}
	}

	public String getShell() {
		return shell;
	}

	public void setShell(String shell) {
		this.shell = shell;
	}
}